package com.leyou.item.service;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.dto.CartDTO;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.vo.PageResult;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.mapper.StockMapper;
import com.leyou.item.pojo.*;
import com.netflix.discovery.converters.Auto;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class GoodsService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private SpuDetailMapper spuDetailMapper;


    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandService brandService;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;


    public PageResult<Spu> querySpuByPage(Integer page, Integer rows,Boolean saleable,String key){

        //1.分页
        PageHelper.startPage(page,rows);


        //2.条件
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();

        //是否上下架查询
        if(saleable != null){
            criteria.andEqualTo("saleable",saleable);
        }

        //是否有搜索条件
        if(StringUtils.isNotBlank(key)){
            criteria.andLike("title","%"+ key +"%");
        }

        //默认排序

        example.setOrderByClause("last_update_time desc");


        //3查询
        List<Spu> spus = spuMapper.selectByExample(example);

        //判断是否有结果
        if(CollectionUtils.isEmpty(spus)){
            throw  new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }


        //封装三级分类和品牌名
        loadCategoryAndBrandName(spus);


        //封装返回结果
        PageInfo pageInfo = new PageInfo(spus);

        return new PageResult<Spu>(pageInfo.getTotal(),spus);
    }

    private void loadCategoryAndBrandName(List<Spu> spus) {
        for (Spu spu : spus) {
            //封装三级分类
            List<String> names = categoryService.queryByids(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()))
                    .stream().map(Category::getName).collect(Collectors.toList());

           spu.setCategoryName(StringUtils.join(names,"/"));

           //封装品牌名称
          spu.setBrandName(brandService.queryById(spu.getBrandId()).getName());
        }


    }


    /**
     * 商品的新增
     * @param spu
     */
    @Transactional
    public void saveGoods(Spu spu) {
        //新增Spu
        spu.setId(null);
        spu.setCreateTime(new Date());
        spu.setLast_update_time(spu.getCreateTime());
        spu.setSaleable(true);
        spu.setValid(true);

        int count = spuMapper.insert(spu);
        if(count != 1){
            throw new LyException(ExceptionEnum.GOODS_SAVE_ERROR);
        }
        //新增SpuDatile
        SpuDetail spuDetail = spu.getSpuDetail();
        spuDetail.setSpuId(spu.getId());

        spuDetailMapper.insert(spuDetail);

        //新增sku和stock
        saveSkuAndStock(spu);

        //发生mq消息
        amqpTemplate.convertAndSend("item.insert",spu.getId());
    }

    /**
     * 新增Sku和stock
     * @param spu
     */
    public void saveSkuAndStock(Spu spu){
        int count =0;
        //新增SKU
        List<Sku> skus = spu.getSkus();

        List<Stock> stockList = new ArrayList<>();

        for (Sku sku : skus) {
            sku.setSpuId(null);
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(sku.getCreateTime());
            sku.setSpuId(spu.getId());
            count = skuMapper.insert(sku);
            if(count != 1){
                throw new LyException(ExceptionEnum.GOODS_SAVE_ERROR);
            }
            //新增库存
            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());
            stockList.add(stock);
        }

        count = stockMapper.insertList(stockList);
        if(count !=  stockList.size()){
            throw new LyException(ExceptionEnum.GOODS_SAVE_ERROR);
        }
    }

    /**
     * 商品的修改
     * @param spu
     */
    @Transactional
    public void updateGoods(Spu spu){
        if (spu.getId() == null){
            throw  new LyException(ExceptionEnum.GOODS_ID_CANNOT_BE_NULL);
        }

        Sku sku = new Sku();
        sku.setSpuId(spu.getId());

        //查询sku
        List<Sku> skuList = skuMapper.select(sku);

        if(!CollectionUtils.isEmpty(skuList)){
            //删除sku
            skuMapper.delete(sku);

            //删除stock
            List<Long> ids = skuList.stream().map(Sku::getId).collect(Collectors.toList());
            stockMapper.deleteByIdList(ids);
        }

        //修改spu
        spu.setValid(null);
        spu.setSaleable(null);
        spu.setLast_update_time(new Date());
        spu.setCreateTime(null);

        int count = spuMapper.updateByPrimaryKeySelective(spu);

        if(count != 1){
            throw  new LyException(ExceptionEnum.GOODS_UPDATE_ERROR);
        }

        //修改detail
        count = spuDetailMapper.updateByPrimaryKeySelective(spu.getSpuDetail());
        if(count != 1){
            throw  new LyException(ExceptionEnum.GOODS_UPDATE_ERROR);
        }
        //新增sku和stock
        saveSkuAndStock(spu);

        //发生mq消息
        amqpTemplate.convertAndSend("item.update",spu.getId());
    }


    public SpuDetail queryDetailById(Long spuId) {
        SpuDetail spuDetail = spuDetailMapper.selectByPrimaryKey(spuId);

        System.out.println("goods..." +spuDetail);

        if(spuDetail == null){
            throw new LyException(ExceptionEnum.GOODS_DETAIL_NOT_FOND);
        }

        return  spuDetail;


    }

    public List<Sku> querySkuBySpuId(Long spuId) {
        Sku sku = new Sku();
        sku.setSpuId(spuId);
        List<Sku> skus = skuMapper.select(sku);
        if(CollectionUtils.isEmpty(skus)){
            throw  new LyException(ExceptionEnum.GOODS_SKU_NOT_FOND);
        }
        //获得所以sku的id
        List<Long> ids = skus.stream().map(Sku::getId).collect(Collectors.toList());
        //查询库存
        loadStockInSku(ids,skus);
        return  skus;
    }

    public void loadStockInSku(List<Long> ids,List<Sku> skus){

        List<Stock> stockList = stockMapper.selectByIdList(ids);
        if(CollectionUtils.isEmpty(stockList)){
            throw new LyException(ExceptionEnum.GOODS_STOCK_NOT_FOUND);
        }


        //我们把查询到的所有stock变成一个map，器key是sku的id 值的库存，在Sku中可以通过Sku的id值来map集合中快速的查到库存
        Map<Long, Integer> stockMap = stockList.stream().collect(Collectors.toMap(Stock::getSkuId, Stock::getStock));
        skus.forEach(s->s.setStock(stockMap.get(s.getId())));
    }

    /**
     * 根据spu的id 查询spu的对象sku和详情。
     * @param id
     * @return
     */
    public Spu querySpuById(Long id) {
        //查询spu
        Spu spu = spuMapper.selectByPrimaryKey(id);
        if(spu == null){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }

        //查询sku
        List<Sku> skus = querySkuBySpuId(id);
        spu.setSkus(skus);
        //查询详情
        SpuDetail spuDetail = queryDetailById(id);
        spu.setSpuDetail(spuDetail);


        return spu;
    }

    /**
     * 通过sku的id查询sku的对象
     * @param ids
     * @return
     */
    public List<Sku> querySkuByIds(List<Long> ids) {
        List<Sku> skus = skuMapper.selectByIdList(ids);
        if(CollectionUtils.isEmpty(skus)){
            throw new LyException(ExceptionEnum.GOODS_SKU_NOT_FOND);
        }
        loadStockInSku(ids,skus);
        return skus;
    }

    /**
     * 减少商品的库存
     * @param carts
     */
    @Transactional
    public void decreaseStock(List<CartDTO> carts) {

        for (CartDTO cart : carts) {
           //减少库存
            int count = stockMapper.decreaseStock(cart.getSkuId(), cart.getNum());
            if (count != 1){
                throw  new LyException(ExceptionEnum.STOCK_NOT_ENOUGH);
            }
        }

    }
}
